package v9.assist.script

import sample.ui.ConsoleLayout
import sample.ui.AppDispatchers
import sample.ui.Properties
import kotlinx.coroutines.Job
import kotlinx.coroutines.delay
import kotlinx.coroutines.script.Block
import kotlinx.coroutines.script.C
import kotlinx.coroutines.script.Controller
import kotlinx.coroutines.script.Controller.Companion.processExitGame
import kotlinx.coroutines.script.tes.DiskLogUtils
import kotlinx.coroutines.script.tes.appScopeLaunch
import kotlinx.coroutines.script.tes.printLog
import kotlinx.coroutines.script.tes.pt
import kotlinx.coroutines.script.tes.readByDisk
import kotlinx.coroutines.script.tes.shake
import kotlinx.coroutines.script.tes.toast
import kotlinx.coroutines.script.accAutoAtk
import kotlinx.coroutines.script.tes.random
import v9.assist.access.accClick
import v9.assist.access.accPathfinding


import v9.assist.access.btnApplyAccept
import v9.assist.access.btnApplyMenu
import v9.assist.access.btnApplyPopMenu
import v9.assist.access.btnApplyRefuse
// import v9.assist.access.btnAtvConfirm
import v9.assist.access.btnCloseable
import v9.assist.access.btnEditFriendClose
import v9.assist.access.btnInteract
import v9.assist.access.btnInviteBlackClose
import v9.assist.access.btnInviteCancel
import v9.assist.access.btnInviteConfirm
import v9.assist.access.btnPopApplyClose
import v9.assist.access.btnPopTxtCancel
import v9.assist.access.btnPopTxtConfirm
import v9.assist.access.btnRandomBuff
import v9.assist.access.btnReviveByOtherCancel
import v9.assist.access.btnReviveInCity
import v9.assist.access.btnReviveInHere
import v9.assist.access.btnSceneHideState
import v9.assist.access.btnSceneInviteGroupAllClose
import v9.assist.access.btnScreenCenter
import v9.assist.access.btnSelectRole
import v9.assist.access.btnSkipAnim
import v9.assist.access.releaseLastGestures

import v9.assist.analyst.MODE_PATHFINDING_P1
import v9.assist.analyst.MODE_PATHFINDING_P2
import v9.assist.analyst.MODE_PATHFINDING_P3
import v9.assist.analyst.PAGE_APPLY
import v9.assist.analyst.PAGE_APPLY_EMPTY
import v9.assist.analyst.PAGE_BASE_MENU
import v9.assist.analyst.PAGE_BE_INVITED
import v9.assist.analyst.PAGE_BE_INVITED_BLACK_GROUP
import v9.assist.analyst.PAGE_BOSS_DIRECT_OR_BUFF
import v9.assist.analyst.PAGE_CLOSEABLE
import v9.assist.analyst.PAGE_EDIT_FRIEND_NAME
import v9.assist.analyst.PAGE_INITIAL
import v9.assist.analyst.PAGE_MAIN
import v9.assist.analyst.PAGE_POP_TEXT
import v9.assist.analyst.PAGE_REVIVE
import v9.assist.analyst.PAGE_REVIVE_BY_OTHER
import v9.assist.analyst.PAGE_ROOT_ENTER
import v9.assist.analyst.PAGE_ROOT_ENTER_TIP
import v9.assist.analyst.PAGE_SCENE_COMPLETED
import v9.assist.analyst.PAGE_SCENE_ENTER
import v9.assist.analyst.PAGE_SCENE_GROUP_INVITE_PLAYER
import v9.assist.analyst.PAGE_SELECT_ROLE
import v9.assist.analyst.PAGE_SKIP
import v9.assist.analyst.PAGE_TALK_BLACKSMITH
import v9.assist.analyst.PAGE_TALK_NPC
import v9.assist.analyst.anaClearSceneSettle
import v9.assist.analyst.anaLastHasBackpack100Ts
import v9.assist.analyst.anaLastHasEnemyNameTs
import v9.assist.analyst.anaLastHasInteractTs
import v9.assist.analyst.anaLastSMapYWFeature10Ts
import v9.assist.analyst.anaLastSMapYWFeature11Ts
import v9.assist.analyst.anaLastSMapYWFeature12Ts
import v9.assist.analyst.anaLastSMapYWFeature13Ts
import v9.assist.analyst.anaLastSMapYWFeature15Ts
import v9.assist.analyst.anaLastSMapYWFeature16Ts
import v9.assist.analyst.anaLastSMapYWFeature17Ts
import v9.assist.analyst.anaLastSMapYWFeature18Ts
import v9.assist.analyst.anaLastSMapYWFeature19Ts
import v9.assist.analyst.anaLastSMapYWFeature20Ts
import v9.assist.analyst.anaLastSMapYWFeature21Ts
import v9.assist.analyst.anaLastSMapYWFeature22Ts
import v9.assist.analyst.anaLastSMapYWFeature23Ts
import v9.assist.analyst.anaLastSMapYWFeature24Ts
import v9.assist.analyst.anaLastSMapYWFeature25Ts
import v9.assist.analyst.sceneYWStateToP4Ts
import v9.assist.analyst.anaLastSMapYWFeature3Ts
import v9.assist.analyst.anaLastSMapYWFeature4Ts
import v9.assist.analyst.anaLastSMapYWFeature7Ts
import v9.assist.analyst.anaLastSMapYWFeature8Ts
import v9.assist.analyst.anaLastSMapYWFeature9Ts
import v9.assist.analyst.anaLastSceneSettleTs
import v9.assist.analyst.anaPathfindingModeYW
import v9.assist.analyst.anaUpdateExcludeEnemyName
import v9.assist.analyst.setupAnalystScene
import v9.assist.analyst.analystInitialized
import v9.assist.analyst.angleByRoad
import v9.assist.analyst.blockBlacksmith
import v9.assist.analyst.blockBlueDoor
import v9.assist.analyst.blockEliteEnemyBoss
import v9.assist.analyst.bsAcceptApply
import v9.assist.analyst.bsAcceptInvite
import v9.assist.analyst.bsBossBeside
import v9.assist.analyst.bsEnemy
import v9.assist.analyst.bsHasApplyDot
import v9.assist.analyst.bsHasEnemy
import v9.assist.analyst.bsHasInteract
import v9.assist.analyst.bsHasReviveRightBtn
import v9.assist.analyst.bsHasTransmitting
import v9.assist.analyst.bsPage
import v9.assist.analyst.bsPlayerHpLosing
import v9.assist.analyst.bsSceneSettle
import v9.assist.analyst.bsSceneSettleBlacksmith
import v9.assist.analyst.counterActionStopped
import v9.assist.analyst.fsInfo

import v9.assist.analyst.lastEliteEnemyBossTs
import v9.assist.analyst.lastSMapTargetToNpcTs
import v9.assist.analyst.sceneYWStateToP2Ts
import kotlin.math.max

private var scriptInError = false
private var n: Long? = null // 检查CDK用的时间戳标记
private var job: Job? = null

private var sLastFeature1Ts = 0L
private var sLastFeature2Ts = 0L
private var sLastFeature3Ts = 0L //
private var sLastFeature4Ts = 0L //
private var sLastFeature5Ts = 0L //
private var sLastFeature6Ts = 0L //
private var sLastFeature7Ts = 0L //
private var sLastFeature8Ts = 0L //
private var sLastFeature9Ts = 0L //
private var sLastFeature10Ts = 0L
private var sLastFeature11Ts = 0L //死路起点
private var sLastFeature12Ts = 0L // P4死路
private var sLastFeature13Ts = 0L
private var sLastFeature14Ts = 0L
private var sLastFeature15Ts = 0L
private var sLastFeature16Ts = 0L
private var sLastFeature17Ts = 0L
private var sLastFeature18Ts = 0L
private var sLastFeature19Ts = 0L
private var counterLastFeature9 = 0L //切换尝试
private var sLastFeature20Ts = 0L
private var sLastFeature21Ts = 0L
private var sLastFeature22Ts = 0L
private var sLastFeature23Ts = 0L
private var sLastFeature24Ts = 0L
private var sLastFeature25Ts = 0L
private var sLastFeature26Ts = 0L

fun startSceneYW() {
    job?.cancel()
    job = appScopeLaunch(AppDispatchers.Script) {
        scriptInError = false
        xCounterNetRetry = Properties.netRetryCount
        xLastAtvTs = System.currentTimeMillis()
        xLastSceneEnterTs = System.currentTimeMillis() // 现在只记录副本开始时间
        setupAnalystScene(C.S_YW)
        anaUpdateExcludeEnemyName("O")
        n = System.currentTimeMillis()
        delay(200) 
        while(Controller.isRunning && !scriptInError) {
            checkScriptError()
            if (!analystInitialized) {
                printLog { "Script invoking not ready" }
                ConsoleLayout.outputText("等待首帧截屏.连续出现重启脚本")
                toast("等待首帧截屏.连续出现重启脚本")
                delay(1000) // 刚开始没准备好
            } else {
                val timestamp = System.currentTimeMillis()
                processFsYW()
                val using = System.currentTimeMillis() - timestamp
                if (using < 10) delay(if (bsPage == PAGE_INITIAL) 800L.shake(50) else 200L.shake(5))
            }
        }
    }
}

fun stopSceneYW() {
    xBossDirectOrBuff = false
    xLastAtvTs = 0 // 不能少
    job?.cancel()
    anaClearSceneSettle()
}

suspend fun processFsYW() {
    fsInfo.also { if (bsPage != SCRIPT_MAIN) printLog { "processFs $anaPathfindingModeYW $anaPathfindingModeYW $anaPathfindingModeYW $anaPathfindingModeYW $it" } }

    if (bsPage == PAGE_BE_INVITED) {
        val widget = if (bsAcceptInvite) btnInviteConfirm else btnInviteCancel
        accClick(widget, afterDelay = 500)
        random.nextInt(360).also { 
            listOf(it, it, it, it).forEachIndexed { index, i -> 
                printLog { "script 随机移动 $index" }
                accPathfinding(i)
            }
            releaseLastGestures()
        }
    } else if (bsPage == PAGE_REVIVE) {
        if (bsHasReviveRightBtn) {
            accClick(btnReviveInHere, afterDelay = 333)
        } else {
            accClick(btnReviveInCity, afterDelay = 333)
            if (xBossDirectOrBuff) xLastBossDirectOrBuffTs = System.currentTimeMillis()
        }
        anaPathfindingModeYW = MODE_PATHFINDING_P1 // 复活后模式还原。副本起点也还原
        xLastAtvTs = System.currentTimeMillis()
        xLastReviveTs = System.currentTimeMillis()
    } else if (bsPage == PAGE_SCENE_ENTER) {
        accSceneEnter()
        anaPathfindingModeYW = MODE_PATHFINDING_P1
    } else if (bsPage == PAGE_BASE_MENU) {
        accClick(btnScreenCenter, afterDelay = 2000)
    } else if (bsPage == PAGE_SKIP) {
        delay(500)
        accClick(btnSkipAnim, afterDelay = 2500)
        listOf(316, 316, 316, 316).forEachIndexed { index, i ->
            printLog { "script 画面跳过 $index" }
            accPathfinding(i)
        }
        releaseLastGestures()
        xLastAtvTs = System.currentTimeMillis()
    } else if (bsPage == PAGE_POP_TEXT) {
        accClick(btnPopTxtCancel, afterDelay = 2400)
        listOf(320, 320, 320, 320, 320, 320, 320).forEachIndexed { index, i ->
            printLog { "script 防止卡地图移动 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        accClick(btnInteract, afterDelay = 1500)
        accClick(btnPopTxtConfirm, afterDelay = 2000) // 如果是在外面的入口卡住
        xLastAtvTs = System.currentTimeMillis() // 延长时间
    } else if (bsPage == PAGE_BE_INVITED_BLACK_GROUP) {
        delay(500)
        accClick(btnInviteBlackClose, afterDelay = 1500)
    } else if (bsPage == PAGE_EDIT_FRIEND_NAME) {
        delay(500)
        accClick(btnEditFriendClose, afterDelay = 1500)
        random.nextInt(360).also { 
            listOf(it, it, it, it).forEachIndexed { index, i -> 
                printLog { "script 随机移动 $index" }
                accPathfinding(i)
            }
            releaseLastGestures()
        }
    } else if (bsPage == PAGE_SCENE_GROUP_INVITE_PLAYER) {
        delay(500)
        accClick(btnSceneInviteGroupAllClose, afterDelay = 1500)
        random.nextInt(360).also { 
            listOf(it, it, it, it).forEachIndexed { index, i -> 
                printLog { "script 随机移动 $index" }
                accPathfinding(i)
            }
            releaseLastGestures()
        }
    } else if (bsPage == PAGE_TALK_BLACKSMITH || bsPage == PAGE_SCENE_COMPLETED
        || bsSceneSettleBlacksmith || bsSceneSettle
    ) {
        if (bsEnemy == "Y" || bsEnemy == "B" || bsEnemy == "P" || blockEliteEnemyBoss != null
            && System.currentTimeMillis() - sLastFeature34Ts > 1000) {
            anaClearSceneSettle()
            sLastFeature34Ts = System.currentTimeMillis()
        }
        else {
            xLastAtvTs = System.currentTimeMillis()
            sceneHandlingSettle(
                blacksmithBy = { blacksmithByBlueDoor(blockBlueDoor) ?: blacksmithByBlacksmith(blockBlacksmith) },
                exitBy = { exitByBlueDoor(blockBlueDoor) ?: exitByBlacksmith(blockBlacksmith) }
            )
        }
    } else if (bsPage == PAGE_TALK_NPC) {
        delay(500)
        accClick(btnScreenCenter, afterDelay = 1500)
        random.nextInt(360).also { 
            listOf(it, it, it, it).forEachIndexed { index, i -> 
                printLog { "script 随机移动 $index" }
                accPathfinding(i)
            }
            releaseLastGestures()
        } // 有这段
    } else if (bsPage == PAGE_APPLY_EMPTY) {
        accClick(btnPopApplyClose, afterDelay = 1000)
    } else if (bsPage == PAGE_APPLY) {
        accClick(if (bsAcceptApply) btnApplyAccept else btnApplyRefuse, afterDelay = 1000)
    } else if (bsPage == PAGE_SELECT_ROLE) {
        accClick(btnSelectRole, afterDelay = 1500)
    } else if (bsPage == PAGE_CLOSEABLE) {
        delay(500)
        accClick(btnCloseable, afterDelay = 3000)
        xLastCloseableTs = System.currentTimeMillis()
    } else if (bsPage == PAGE_BOSS_DIRECT_OR_BUFF) {
        delay(500)
        accClick(btnRandomBuff, afterDelay = 2000)
        xLastBossDirectOrBuffTs = System.currentTimeMillis()
        xBossDirectOrBuff = true
    } else if (bsPage == PAGE_REVIVE_BY_OTHER) {
        accClick(btnReviveByOtherCancel, afterDelay = 1500)
    } else if (bsPage == PAGE_ROOT_ENTER_TIP || bsPage == PAGE_ROOT_ENTER) {
        tryEnterByRelaunch()
    } else if (bsPage == PAGE_MAIN) { // 主页操作
        if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) {
            accAutoAtk(angleByRoad)
            xLastAtvTs = System.currentTimeMillis()
            if (bsHasEnemy) xLastAtkTs = System.currentTimeMillis()
        } else if (
            (System.currentTimeMillis() - xLastBossDirectOrBuffTs < 30000 || (System.currentTimeMillis() - xLastReviveTs < 30000 && xBossDirectOrBuff))
            && System.currentTimeMillis() - anaLastHasEnemyNameTs > 3000
            && blockBlueDoor != null) {
            listOf(355, 355, 355).forEachIndexed { index, i ->
                printLog { "scriptYW 节点.直通直接去bossA $index" } //开门这里是往上走
                accPathfinding(i, if (index >= 2) btnInteract else null)
            }
            accClick(btnInteract, afterDelay = 500)
        } else if (bsHasTransmitting
            && !bsPlayerHpLosing
            && System.currentTimeMillis() - anaLastHasInteractTs < 9000) {
            // 开门流程
            xCounterInteract = 0
            delay(500)
        } else if (System.currentTimeMillis() - anaLastHasBackpack100Ts < 50000
            && (System.currentTimeMillis() - xLastAtkTs > 3000 || System.currentTimeMillis() - anaLastSceneSettleTs < 10000)
            && System.currentTimeMillis() - sLastFeature29Ts > 50000) {
            printLog { "script 满背包尝试分解" }
            tryPetBlacksmithSubmit()
            sLastFeature29Ts = System.currentTimeMillis()
        } else if (bsHasInteract && !bsPlayerHpLosing
            && System.currentTimeMillis() - xLastUnknownTs > 8000
            && System.currentTimeMillis() - xLastSceneEnterTs > 12000
            && System.currentTimeMillis() - lastEliteEnemyBossTs > 16000  // 击杀boss后不要乱点
            && System.currentTimeMillis() - xLastBossDirectOrBuffTs > 20000
            && !bsSceneSettle && !bsSceneSettleBlacksmith
            && System.currentTimeMillis() - anaLastSceneSettleTs > 15000
            && System.currentTimeMillis() - xLastReviveTs > 15000
            && System.currentTimeMillis() - xLastCloseableTs > 10000) {
            xCounterInteract++
            if (xCounterInteract % 6 == 0) { // 超过？秒即可。 互动进度条 6秒够了
                printLog { "新增移动。避免背包满了" }
                accPathfinding(angleByRoad)
                random.nextInt(360).also { 
                    listOf(it, it, it, it).forEachIndexed { index, i ->
                        printLog { "script 随机移动 $index" }
                        accPathfinding(i)
                    }
                    releaseLastGestures()
                }
            }

            val delay = // NPC解救互动连续点击慢一点
                if (System.currentTimeMillis() - lastSMapTargetToNpcTs < 5000) 2500L
                else 1500L
            accClick(btnInteract, afterDelay = delay)
        } else if (bsHasApplyDot && Properties.inviteAutoAccept != 0) {
            accClick(btnApplyMenu, afterDelay = 500)
            accClick(btnApplyPopMenu, afterDelay = 1000)
        } else {
            // 寻路流程
            xCounterInteract = 0
            sceneYWSpecialHandling1()
            accPathfinding(sceneAngleByRoad(), pathfindingWith())
        }
    } else if (bsPage != PAGE_MAIN) {
        scriptHandlingUnknown()
    }
}

private fun pathfindingWith(): String? {
    if (!bsSceneSettle && !bsSceneSettleBlacksmith
        && System.currentTimeMillis() - anaLastSceneSettleTs > 20000
        && System.currentTimeMillis() - xLastSceneEnterTs > 10000
    ) {
        if (System.currentTimeMillis() - lastSMapTargetToNpcTs < 3000
            && System.currentTimeMillis() - sLastAccInteractTs > 500) {
            printLog { "pathfindingWith btnInteract by scene to P1 npc" }
            sLastAccInteractTs = System.currentTimeMillis()
            return btnInteract
        }
    }
    return null
}


private suspend fun sceneYWSpecialHandling1() {
    if (System.currentTimeMillis() - xLastAtkTs > 240000
        && System.currentTimeMillis() - xLastAtvTs > 240000 // 脚本开启后
        && System.currentTimeMillis() - xLastSceneExitTs > 120000) {
        printLog { "scriptYW 节点.超时退出" }
        sceneExit()
        anaPathfindingModeYW = MODE_PATHFINDING_P1 // 重制
    } else if (counterActionStopped > 30 && System.currentTimeMillis() - xLastAtkTs > 3000
        && System.currentTimeMillis() - sLastFeature33Ts > 60000) {
        printLog { "script 节点.原地不动." }
        releaseLastGestures()
//        accClick(btnSmallMap, afterDelay = 2000)
        counterActionStopped = 0
        sLastFeature33Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature3Ts < 2000
        && System.currentTimeMillis() - sLastFeature3Ts > 10000) {
        listOf(185, 185, 185).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.直通直接去bossC $index" }
            accPathfinding(i, if (index >= 2) btnInteract else null)
        }
        accClick(btnInteract, afterDelay = 500)
        sLastFeature3Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature4Ts < 2000
        && System.currentTimeMillis() - sLastFeature4Ts > 6000) {
        if (!xSceneHideState) {
            printLog { "script. 收起副本状态 B 遗忘展开" }
            accClick(btnSceneHideState, afterDelay = 500)  //accClick(btnSceneOpenState, afterDelay = 500)
            xSceneHideState = true
        }
        listOf(190, 190, 190, 190, 190, 190,
            190, 190, 190, 190, 260, 260).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1切换P2去往下开门 $index" }
            accPathfinding(i)
        }
        releaseLastGestures()
        accClick(btnInteract, afterDelay = 1000) // 开门中
        var c = 0
        while (c++ < 5 && System.currentTimeMillis() - anaLastHasInteractTs < 2000) {
            printLog { "互动等待" }
            delay(1000L)
        }
        listOf(240, 250).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1切换P2去往下开门 进门 $index" }
            accPathfinding(i)
        }

        anaPathfindingModeYW = MODE_PATHFINDING_P2
        sceneYWStateToP2Ts = System.currentTimeMillis()
        sLastFeature4Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature9Ts < 2000
        && System.currentTimeMillis() - sLastFeature9Ts > 6000) {
        printLog { "scriptYW 节点.P1去开门的门上侧 [尝试次数$counterLastFeature9]" }
        listOf(90, 110, 180, 180, 190, 180, 270).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1去开门的门上侧 $index" }
            accPathfinding(i)
        }
        releaseLastGestures()
        accClick(btnInteract, afterDelay = 1000) // 开门中
        var c = 0
        while (c++ < 5 && System.currentTimeMillis() - anaLastHasInteractTs < 2000) {
            printLog { "互动等待" }
            delay(1000L)
        }
        listOf(230, 240).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1去开门的门上侧B2 进门 $index" }
            accPathfinding(i)
        }

        if (System.currentTimeMillis() - sLastFeature9Ts > 30000) counterLastFeature9 = 0
        if (System.currentTimeMillis() - sLastFeature9Ts < 30000) {
            counterLastFeature9++
        }
        if (counterLastFeature9 > 5) {
            printLog { "scriptYW 节点.连续尝试打不开门.可能是远古模式." }
            anaPathfindingModeYW = MODE_PATHFINDING_P3
        } else {
            anaPathfindingModeYW = MODE_PATHFINDING_P2
            sceneYWStateToP2Ts = System.currentTimeMillis()
        }
        sLastFeature9Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature7Ts < 2000
        && System.currentTimeMillis() - sLastFeature7Ts > 6000) {
        listOf(280, 320, 0, 0, 0, 10, 20, 30, 40,
            45, 45, 45).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P3从开始开锁的门去最右边 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature7Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature8Ts < 2000
        && System.currentTimeMillis() - sLastFeature8Ts > 6000) {
        listOf(90, 100, 180, 190, 210, 220, 220, 220, 230,
            220, 220, 210, 220, 210, 230, 220).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.去最终boss $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        releaseLastGestures()
        repeat(3) {
            if (System.currentTimeMillis() - lastEliteEnemyBossTs > 2000) {
                printLog { "scriptYW 节点.去最终boss 等待boss出现" }
                delay(1000L)
            }
        }
        sLastFeature8Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature11Ts < 2000
        && System.currentTimeMillis() - sLastFeature11Ts > 6000) {
        listOf(160, 140, 160, 140, 160, 135, 110, 90, 70,
            60, 60, 30, 0, 330).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.起点死路 $index" }
            accPathfinding(i, if (index >= 2) btnInteract else null)
        }
        sLastFeature11Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature12Ts < 2000
        && System.currentTimeMillis() - sLastFeature12Ts > 6000) {
        listOf(45, 45, 45, 0, 0, 0, 0, 0,
            0, 0, 0, 0, 340, 340, 340).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P4死路 $index" }
            accPathfinding(i, if (index >= 2) btnInteract else null)
        }
        anaPathfindingModeYW = MODE_PATHFINDING_P3 // 稳一手.送地图上面触发P3变P4
        sLastFeature12Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature10Ts < 2000
        && System.currentTimeMillis() - sLastFeature10Ts > 6000) {
        listOf(330, 330, 330, 330, 330).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.副本外入口 $index" }
            accPathfinding(i, if (index >= 3) btnInteract else null)
        }
        accClick(btnPopTxtConfirm, afterDelay = 2000) // 如果是在外面的入口卡住
        sLastFeature10Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature13Ts < 2000
        && System.currentTimeMillis() - sLastFeature13Ts > 6000) {
        listOf(160, 160, 160, 250, 270, 300).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P2 第1个Boss击破后左下角互动门口上侧 $index" }
            accPathfinding(i, if (index >= 2) btnInteract else null)
        }
        sLastFeature13Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - lastEliteEnemyBossTs < 2000
        && anaPathfindingModeYW == MODE_PATHFINDING_P1
        && System.currentTimeMillis() - xLastReviveTs > 32000 // 起点复活到boss
        && System.currentTimeMillis() - sceneYWStateToP4Ts > 16000
        && System.currentTimeMillis() - sLastFeature8Ts > 16000
        && System.currentTimeMillis() - sLastFeature18Ts > 16000
        && System.currentTimeMillis() - xLastAtkTs > 16000
        && System.currentTimeMillis() - sLastFeature14Ts > 16000) {
        listOf(150, 140, 150, 140, 150, 140, 150, 140, 150, 140, 150, 140,).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1 第1个Boss小怪没清干净 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature14Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature15Ts < 2000
        && System.currentTimeMillis() - sLastFeature15Ts > 6000) {
        listOf(140, 130, 90, 80).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P3卡出去的门口 $index" }
            accPathfinding(i)
        }
        sLastFeature15Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature16Ts < 2000
        && System.currentTimeMillis() - sLastFeature16Ts > 6000) {
        listOf(140, 130, 90, 80).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P3最右边的卡门.右下角走两步微调 $index" }
            accPathfinding(i)
        }
        sLastFeature16Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature17Ts < 2000
        && System.currentTimeMillis() - sLastFeature17Ts > 6000) {
        listOf(270, 0, 30).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P3最右边的卡门.左上角走两步微调 $index" }
            accPathfinding(i)
        }
        sLastFeature17Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature18Ts < 2000
        && System.currentTimeMillis() - sLastFeature18Ts > 6000) {
        listOf(35, 30, 35, 40, 35, 50, 35, 40, 35, 30, 35).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P4走过头了.回头触发Boss A $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature18Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature24Ts < 2000
        && System.currentTimeMillis() - sLastFeature24Ts > 6000) {
        listOf(65, 45, 65, 55, 65, 45, 65, 55, 65, 45, 65,).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P4走过头了.回头触发Boss B $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature24Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature25Ts < 2000
        && System.currentTimeMillis() - sLastFeature25Ts > 6000) {
        listOf(10, 15, 10, 15, 20, 15, 20, 15, 10, 15, 10,).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P4走过头了.回头触发Boss C1 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature25Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature19Ts < 2000
        && System.currentTimeMillis() - sLastFeature19Ts > 6000) {
        listOf(190, 220, 270, 330).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1开局路往上.卡点往左下走一步 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature19Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature20Ts < 2000
        && System.currentTimeMillis() - sLastFeature20Ts > 6000) {
        listOf(45, 50, 45, 50, 45, 50, 45, 50).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1开局路左下区域死路回到主径 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature20Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature21Ts < 2000
        && System.currentTimeMillis() - sLastFeature21Ts > 6000) {
        listOf(230, 250, 270).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.节点.P3右上测墙边卡点 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature21Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature22Ts < 2000
        && System.currentTimeMillis() - sLastFeature22Ts > 8000) {
        // 120 140 120 140 atk 80 atk
        listOf(120, 140, 120, 140, 80).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P1开局卡树怪 $index" }
            if (index >= 3) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature22Ts = System.currentTimeMillis()
    } else if (System.currentTimeMillis() - anaLastSMapYWFeature23Ts < 2000
        && System.currentTimeMillis() - sLastFeature23Ts > 8000) {
        // 300 310 300 310 300 310 300 310
        listOf(300, 310, 300, 310, 300, 310, 300, 310).forEachIndexed { index, i ->
            printLog { "scriptYW 节点.P3 实际在boss.直通来的 $index" }
            if (bsHasEnemy || bsPlayerHpLosing || bsBossBeside) accAutoAtk(i)
            else accPathfinding(i)
        }
        sLastFeature23Ts = System.currentTimeMillis()
    }




}

private fun blacksmithByBlueDoor(blueDoor: Block?): Block? {
    if (blueDoor == null) return null
    return Block("铁匠", blueDoor.x + 20.pt, blueDoor.y - 8.pt, 0, 0)
}
private fun blacksmithByBlacksmith(blacksmith: Block?): Block? {
    if (blacksmith == null) return null
    return Block("铁匠fixed", blacksmith.x + 2.pt, blacksmith.y - 2.pt, 0, 0)
}
private fun exitByBlueDoor(blueDoor: Block?): Block? {
    if (blueDoor == null) return null
    return Block("小地图传送门fixed", blueDoor.x - 2.pt, blueDoor.y + 2.pt, 0, 0)
}
private fun exitByBlacksmith(blacksmith: Block?): Block? {
    if (blacksmith == null) return null
    return Block("小地图传送门By铁匠", blacksmith.x - 20.pt, blacksmith.y + 8.pt, 0, 0)
}

private suspend fun checkScriptError() {
    if (xLastAtvTs == 0L) {
        return
    }
    if (xScriptEndTs > 0 && System.currentTimeMillis() > xScriptEndTs) {
        scriptInError = true
        processExitGame("定时结束(${Properties.stopCountdown}秒)")
        DiskLogUtils.saveToDisk()
    }
    val timeout = Properties.scriptStopTimeout * 1000L   // 超过分钟没有敌人停止脚本
    xAtvLeftTime = max(0, timeout - (System.currentTimeMillis() - xLastAtvTs))
    if (System.currentTimeMillis() - xLastAtvTs > timeout) {
        scriptInError = true
        processExitGame("${C.ERROR_END}=${timeout / 1000}")
        DiskLogUtils.saveToDisk()
    }
    val ne = n
    if (ne != null && System.currentTimeMillis() - ne > timeout
        && System.currentTimeMillis() - lastEliteEnemyBossTs > timeout) {
        // 还有一种情况. 就是已经运行了x分钟了.但是没有boss 可能卡遗迹了
        scriptInError = true
        processExitGame("${C.ERROR_END}=BossLoss")
        DiskLogUtils.saveToDisk()
    }
    if (ne != null && System.currentTimeMillis() - ne > 198123L) {
        val sp = "j#s#l#t#z#m#p#e#r#a".split("#")
        var pass = true
        sp.forEach {
            if (pass && readByDisk(it).isNullOrEmpty()) pass = false
        }
        printLog { "j#s#l#t#z#m#p#e#r#a [pass:$pass]" }
        if (!pass) scriptInError = true
        else n = null
    }
}